package controllers

import (
	"simple-crm/models"
	"simple-crm/utils"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type PartnerController struct {
	DB *gorm.DB
}

type PartnerRequest struct {
	Name        string `json:"name" binding:"required"`
	Type        string `json:"type" binding:"required"`
	City        string `json:"city" binding:"required"`
	Subjects    string `json:"subjects" binding:"required"`
	Contact     string `json:"contact"`
	Phone       string `json:"phone"`
	Email       string `json:"email"`
	Address     string `json:"address"`
	WebhookURL  string `json:"webhook_url"`
	APIKey      string `json:"api_key"`
	Priority    int    `json:"priority"`
	Status      string `json:"status"`
	Description string `json:"description"`
}

type PartnerQuery struct {
	Page     int    `form:"page,default=1"`
	Size     int    `form:"size,default=10"`
	Name     string `form:"name"`
	Type     string `form:"type"`
	City     string `form:"city"`
	Subjects string `form:"subjects"`
	Status   string `form:"status"`
}

// NewPartnerController 创建合作机构控制器
func NewPartnerController(db *gorm.DB) *PartnerController {
	return &PartnerController{DB: db}
}

// GetPartners 获取合作机构列表
func (pc *PartnerController) GetPartners(c *gin.Context) {
	var query PartnerQuery
	if err := c.ShouldBindQuery(&query); err != nil {
		utils.ValidationError(c, err)
		return
	}

	// 构建查询
	db := pc.DB.Model(&models.Partner{})

	// 添加过滤条件
	if query.Name != "" {
		db = db.Where("name LIKE ?", "%"+query.Name+"%")
	}
	if query.Type != "" {
		db = db.Where("type = ?", query.Type)
	}
	if query.City != "" {
		db = db.Where("city = ?", query.City)
	}
	if query.Subjects != "" {
		db = db.Where("subjects LIKE ?", "%"+query.Subjects+"%")
	}
	if query.Status != "" {
		db = db.Where("status = ?", query.Status)
	}

	// 计算总数
	var total int64
	db.Count(&total)

	// 分页查询
	var partners []models.Partner
	offset := (query.Page - 1) * query.Size
	if err := db.Offset(offset).Limit(query.Size).Order("priority DESC, created_at DESC").Find(&partners).Error; err != nil {
		utils.InternalServerError(c, "查询合作机构失败")
		return
	}

	utils.PageSuccess(c, partners, total, query.Page, query.Size)
}

// GetPartner 获取单个合作机构
func (pc *PartnerController) GetPartner(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		utils.BadRequest(c, "合作机构ID无效")
		return
	}

	var partner models.Partner
	if err := pc.DB.Preload("PushRecords.Customer").First(&partner, uint(id)).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			utils.NotFound(c, "合作机构不存在")
		} else {
			utils.InternalServerError(c, "查询合作机构失败")
		}
		return
	}

	utils.Success(c, partner)
}

// CreatePartner 创建合作机构
func (pc *PartnerController) CreatePartner(c *gin.Context) {
	var req PartnerRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.ValidationError(c, err)
		return
	}

	// 检查名称是否已存在
	var count int64
	pc.DB.Model(&models.Partner{}).Where("name = ?", req.Name).Count(&count)
	if count > 0 {
		utils.BadRequest(c, "合作机构名称已存在")
		return
	}

	// 创建合作机构
	partner := models.Partner{
		Name:        req.Name,
		Type:        req.Type,
		City:        req.City,
		Subjects:    req.Subjects,
		Contact:     req.Contact,
		Phone:       req.Phone,
		Email:       req.Email,
		Address:     req.Address,
		WebhookURL:  req.WebhookURL,
		APIKey:      req.APIKey,
		Priority:    req.Priority,
		Status:      req.Status,
		Description: req.Description,
	}

	if err := pc.DB.Create(&partner).Error; err != nil {
		utils.InternalServerError(c, "创建合作机构失败")
		return
	}

	utils.SuccessWithMessage(c, "创建合作机构成功", partner)
}

// UpdatePartner 更新合作机构
func (pc *PartnerController) UpdatePartner(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		utils.BadRequest(c, "合作机构ID无效")
		return
	}

	var req PartnerRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.ValidationError(c, err)
		return
	}

	// 查找合作机构
	var partner models.Partner
	if err := pc.DB.First(&partner, uint(id)).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			utils.NotFound(c, "合作机构不存在")
		} else {
			utils.InternalServerError(c, "查询合作机构失败")
		}
		return
	}

	// 检查名称是否被其他机构使用
	if req.Name != partner.Name {
		var count int64
		pc.DB.Model(&models.Partner{}).Where("name = ? AND id != ?", req.Name, partner.ID).Count(&count)
		if count > 0 {
			utils.BadRequest(c, "合作机构名称已被其他机构使用")
			return
		}
	}

	// 更新合作机构信息
	partner.Name = req.Name
	partner.Type = req.Type
	partner.City = req.City
	partner.Subjects = req.Subjects
	partner.Contact = req.Contact
	partner.Phone = req.Phone
	partner.Email = req.Email
	partner.Address = req.Address
	partner.WebhookURL = req.WebhookURL
	partner.APIKey = req.APIKey
	partner.Priority = req.Priority
	partner.Status = req.Status
	partner.Description = req.Description

	if err := pc.DB.Save(&partner).Error; err != nil {
		utils.InternalServerError(c, "更新合作机构失败")
		return
	}

	utils.SuccessWithMessage(c, "更新合作机构成功", partner)
}

// DeletePartner 删除合作机构
func (pc *PartnerController) DeletePartner(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		utils.BadRequest(c, "合作机构ID无效")
		return
	}

	// 查找合作机构
	var partner models.Partner
	if err := pc.DB.First(&partner, uint(id)).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			utils.NotFound(c, "合作机构不存在")
		} else {
			utils.InternalServerError(c, "查询合作机构失败")
		}
		return
	}

	// 检查是否有关联的推送记录
	var pushCount int64
	pc.DB.Model(&models.PushRecord{}).Where("partner_id = ?", partner.ID).Count(&pushCount)
	if pushCount > 0 {
		utils.BadRequest(c, "该合作机构存在推送记录，无法删除")
		return
	}

	// 软删除合作机构
	if err := pc.DB.Delete(&partner).Error; err != nil {
		utils.InternalServerError(c, "删除合作机构失败")
		return
	}

	utils.SuccessWithMessage(c, "删除合作机构成功", nil)
}

// UpdatePartnerStatus 更新合作机构状态
func (pc *PartnerController) UpdatePartnerStatus(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		utils.BadRequest(c, "合作机构ID无效")
		return
	}

	var req struct {
		Status string `json:"status" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.ValidationError(c, err)
		return
	}

	// 查找合作机构
	var partner models.Partner
	if err := pc.DB.First(&partner, uint(id)).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			utils.NotFound(c, "合作机构不存在")
		} else {
			utils.InternalServerError(c, "查询合作机构失败")
		}
		return
	}

	// 更新状态
	if err := partner.UpdateStatus(pc.DB, req.Status); err != nil {
		utils.InternalServerError(c, "更新合作机构状态失败")
		return
	}

	utils.SuccessWithMessage(c, "更新合作机构状态成功", partner)
}

// GetActivePartners 获取活跃的合作机构
func (pc *PartnerController) GetActivePartners(c *gin.Context) {
	var partners []models.Partner
	if err := pc.DB.Where("status = ?", "active").Order("priority DESC, name ASC").Find(&partners).Error; err != nil {
		utils.InternalServerError(c, "查询合作机构失败")
		return
	}

	utils.Success(c, partners)
}

// GetPartnersByCity 根据城市获取合作机构
func (pc *PartnerController) GetPartnersByCity(c *gin.Context) {
	city := c.Query("city")
	if city == "" {
		utils.BadRequest(c, "城市参数不能为空")
		return
	}

	var partners []models.Partner
	if err := pc.DB.Where("city = ? AND status = ?", city, "active").Order("priority DESC, name ASC").Find(&partners).Error; err != nil {
		utils.InternalServerError(c, "查询合作机构失败")
		return
	}

	utils.Success(c, partners)
}

// GetPartnersBySubject 根据科目获取合作机构
func (pc *PartnerController) GetPartnersBySubject(c *gin.Context) {
	subject := c.Query("subject")
	if subject == "" {
		utils.BadRequest(c, "科目参数不能为空")
		return
	}

	var partners []models.Partner
	if err := pc.DB.Where("subjects LIKE ? AND status = ?", "%"+subject+"%", "active").Order("priority DESC, name ASC").Find(&partners).Error; err != nil {
		utils.InternalServerError(c, "查询合作机构失败")
		return
	}

	utils.Success(c, partners)
}

// GetPartnerStats 获取合作机构统计信息
func (pc *PartnerController) GetPartnerStats(c *gin.Context) {
	type PartnerStats struct {
		TotalPartners  int64 `json:"total_partners"`
		ActivePartners int64 `json:"active_partners"`
		InactivePartners int64 `json:"inactive_partners"`
		MonthlyPushes  int64 `json:"monthly_pushes"`
		ActiveRate     float64 `json:"active_rate"`
		GrowthRate     float64 `json:"growth_rate"`
	}

	var stats PartnerStats

	// 总机构数
	pc.DB.Model(&models.Partner{}).Count(&stats.TotalPartners)

	// 活跃机构数
	pc.DB.Model(&models.Partner{}).Where("status = ?", "active").Count(&stats.ActivePartners)

	// 停用机构数
	stats.InactivePartners = stats.TotalPartners - stats.ActivePartners

	// 本月推送数
	pc.DB.Model(&models.PushRecord{}).Where("DATE_FORMAT(created_at, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m')").Count(&stats.MonthlyPushes)

	// 活跃率
	if stats.TotalPartners > 0 {
		stats.ActiveRate = float64(stats.ActivePartners) / float64(stats.TotalPartners) * 100
	}

	// 增长率（与上月对比）
	var lastMonthPartners int64
	pc.DB.Model(&models.Partner{}).Where("DATE_FORMAT(created_at, '%Y-%m') = DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m')").Count(&lastMonthPartners)
	var thisMonthPartners int64
	pc.DB.Model(&models.Partner{}).Where("DATE_FORMAT(created_at, '%Y-%m') = DATE_FORMAT(NOW(), '%Y-%m')").Count(&thisMonthPartners)
	if lastMonthPartners > 0 {
		stats.GrowthRate = float64(thisMonthPartners-lastMonthPartners) / float64(lastMonthPartners) * 100
	}

	utils.Success(c, stats)
}

// GetCities 获取所有城市列表
func (pc *PartnerController) GetCities(c *gin.Context) {
	type CityInfo struct {
		City  string `json:"city"`
		Count int64  `json:"count"`
	}

	var cities []CityInfo
	if err := pc.DB.Model(&models.Partner{}).Select("city, COUNT(*) as count").Group("city").Order("count DESC").Scan(&cities).Error; err != nil {
		utils.InternalServerError(c, "查询城市列表失败")
		return
	}

	utils.Success(c, cities)
}

// GetPartnerFilters 获取合作机构过滤器选项
func (pc *PartnerController) GetPartnerFilters(c *gin.Context) {
	var cities []string
	var subjects []string

	// 获取所有城市
	pc.DB.Model(&models.Partner{}).Distinct("city").Where("city != ''").Pluck("city", &cities)

	// 获取所有学科（从subjects字段解析）
	var partners []models.Partner
	if err := pc.DB.Select("subjects").Find(&partners).Error; err == nil {
		subjectSet := make(map[string]bool)
		for _, partner := range partners {
			if partner.Subjects != "" {
				// 假设学科以逗号分隔
				subjectList := strings.Split(partner.Subjects, ",")
				for _, subject := range subjectList {
					subject = strings.TrimSpace(subject)
					if subject != "" {
						subjectSet[subject] = true
					}
				}
			}
		}
		// 转换为切片
		for subject := range subjectSet {
			subjects = append(subjects, subject)
		}
	}

	filters := gin.H{
		"cities":   cities,
		"subjects": subjects,
	}

	utils.Success(c, filters)
}

// GetSubjects 获取所有学科列表
func (pc *PartnerController) GetSubjects(c *gin.Context) {
	// 获取所有机构的学科字段
	var partners []models.Partner
	if err := pc.DB.Select("subjects").Find(&partners).Error; err != nil {
		utils.InternalServerError(c, "查询学科列表失败")
		return
	}

	// 解析学科字符串，统计每个学科的出现次数
	subjectCount := make(map[string]int)
	for _, partner := range partners {
		if partner.Subjects != "" {
			// 假设学科以逗号分隔
			subjects := strings.Split(partner.Subjects, ",")
			for _, subject := range subjects {
				subject = strings.TrimSpace(subject)
				if subject != "" {
					subjectCount[subject]++
				}
			}
		}
	}

	// 转换为结果格式
	type SubjectInfo struct {
		Subject string `json:"subject"`
		Count   int    `json:"count"`
	}

	var subjects []SubjectInfo
	for subject, count := range subjectCount {
		subjects = append(subjects, SubjectInfo{
			Subject: subject,
			Count:   count,
		})
	}

	utils.Success(c, subjects)
}

// GetPartnerDetailStats 获取单个合作机构的详细统计
func (pc *PartnerController) GetPartnerDetailStats(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		utils.BadRequest(c, "合作机构ID无效")
		return
	}

	type DetailStats struct {
		TotalPushes   int64   `json:"total_pushes"`
		SuccessPushes int64   `json:"success_pushes"`
		FailedPushes  int64   `json:"failed_pushes"`
		SuccessRate   float64 `json:"success_rate"`
	}

	var stats DetailStats

	// 总推送数
	pc.DB.Model(&models.PushRecord{}).Where("partner_id = ?", uint(id)).Count(&stats.TotalPushes)

	// 成功推送数
	pc.DB.Model(&models.PushRecord{}).Where("partner_id = ? AND status = ?", uint(id), "success").Count(&stats.SuccessPushes)

	// 失败推送数
	stats.FailedPushes = stats.TotalPushes - stats.SuccessPushes

	// 成功率
	if stats.TotalPushes > 0 {
		stats.SuccessRate = float64(stats.SuccessPushes) / float64(stats.TotalPushes) * 100
	}

	utils.Success(c, stats)
}

// GetPartnerActivities 获取合作机构的活动记录
func (pc *PartnerController) GetPartnerActivities(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		utils.BadRequest(c, "合作机构ID无效")
		return
	}

	type Activity struct {
		ID          uint   `json:"id"`
		Type        string `json:"type"`
		Description string `json:"description"`
		Icon        string `json:"icon"`
		CreatedAt   string `json:"created_at"`
	}

	// 获取推送记录作为活动
	var pushRecords []models.PushRecord
	if err := pc.DB.Where("partner_id = ?", uint(id)).Order("created_at DESC").Limit(10).Find(&pushRecords).Error; err != nil {
		utils.InternalServerError(c, "查询活动记录失败")
		return
	}

	var activities []Activity
	for _, record := range pushRecords {
		activity := Activity{
			ID:        record.ID,
			Type:      "push",
			Icon:      "paper-plane",
			CreatedAt: record.CreatedAt.Format("2006-01-02 15:04:05"),
		}

		if record.Status == "success" {
			activity.Description = "客户推送成功"
		} else {
			activity.Description = "客户推送失败"
		}

		activities = append(activities, activity)
	}

	// 获取操作日志作为活动
	var operationLogs []models.OperationLog
	if err := pc.DB.Where("resource_type = ? AND resource_id = ?", "partner", uint(id)).Order("created_at DESC").Limit(5).Find(&operationLogs).Error; err == nil {
		for _, log := range operationLogs {
			activity := Activity{
				ID:          log.ID,
				Type:        "update",
				Description: log.Action + " - " + log.Details,
				Icon:        "edit",
				CreatedAt:   log.CreatedAt.Format("2006-01-02 15:04:05"),
			}
			activities = append(activities, activity)
		}
	}

	utils.Success(c, activities)
}